import React, { useRef, useEffect, useState } from 'react';
import _ from 'lodash';
import { Spin } from 'antd';
import { Editor } from '@craftjs/core';
import RenderNode from './components/renderNode';
import TopBar from './components/topBar';
import LeftMenu from './components/leftMenu';
import ContentCanvas from './components/contentCanvas';
import RightAttribute from './components/rightAttribute';
import PageContainer from '@/components/PageDesignerComponents/pageContainer';
import { combination, atomic, layout } from '@/components/PageDesignerComponents';
import { getComponentDisplayName } from '@/utils/utils';
import styles from './index.less';

// 复合组件（需要序列化配置在Editor.resolver下）
const resolverCombinationComponents = _.assign(
  {},
  ..._.map(combination, ({ component, elementWrappers }) => ({
    [getComponentDisplayName(component)]: component,
    ..._.assign(
      {},
      ...(_.isArray(elementWrappers)
        ? _.map(elementWrappers, (component) => ({
            [getComponentDisplayName(component)]: component,
          }))
        : []),
    ),
  })),
);

// 原子组件（需要序列化配置在Editor.resolver下）
const resolverAtomicComponents = _.assign(
  {},
  ..._.map(atomic, ({ component, elementWrappers }) => ({
    [getComponentDisplayName(component)]: component,
    ..._.assign(
      {},
      ...(_.isArray(elementWrappers)
        ? _.map(elementWrappers, (component) => ({
            [getComponentDisplayName(component)]: component,
          }))
        : []),
    ),
  })),
);

// 布局组件（需要序列化配置在Editor.resolver下）
const resolverLayoutComponents = _.assign(
  {},
  ..._.map(layout, ({ component, elementWrappers }) => ({
    [getComponentDisplayName(component)]: component,
    ..._.assign(
      {},
      ...(_.isArray(elementWrappers)
        ? _.map(elementWrappers, (component) => ({
            [getComponentDisplayName(component)]: component,
          }))
        : []),
    ),
  })),
);

export default () => {
  const drawerRef = useRef(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const handleCloseDrawer = () => {
      const { closeDrawer } = drawerRef.current;
      closeDrawer && closeDrawer();
    };
    document.body.addEventListener('click', handleCloseDrawer);
    return () => {
      document.body.removeEventListener('click', handleCloseDrawer, false);
    };
  }, []);

  return (
    <div className={styles.designContainer}>
      <Spin spinning={loading}>
        <Editor
          resolver={{
            PageContainer,
            ...resolverCombinationComponents,
            ...resolverAtomicComponents,
            ...resolverLayoutComponents,
          }}
          onRender={RenderNode}
        >
          <TopBar loading={loading} setLoading={setLoading} />
          <div className={styles.designContent}>
            <LeftMenu ref={drawerRef} />
            <ContentCanvas />
            <RightAttribute />
          </div>
        </Editor>
      </Spin>
    </div>
  );
};
